Arduino Distance Measurement with Audio | Ultrasonic Sensor + DFPlayer Mini
In this tutorial, we will explore how to use an ultrasonic sensor to measure distance and trigger audio feedback using the DFPlayer Mini module. This project integrates the HC-SR04 ultrasonic sensor, which can measure distances between 2 cm and 400 cm, and the DFPlayer Mini, an MP3 audio player module that plays pre-recorded sounds based on the measured distance. The system will provide audible notifications depending on the proximity of objects, making it a fun and practical project for beginners and intermediate Arduino users.
Components UsedArduino Uno
HC-SR04 Ultrasonic Sensor
DFPlayer Mini
1KOhm Resistor
20 Ohm 1 Watt Speaker
SD Card (formatted FAT16 or FAT32)
Ultrasonic Sensor (HC-SR04) OverviewThe HC-SR04 is one of the most popular ultrasonic sensors used in distance measurement projects. This sensor emits ultrasonic waves and calculates the time it takes for the waves to return after hitting an object, determining the distance.
Pinout
:- VCC – 5V power supply
- TRIG – Trigger pin sends out ultrasonic pulses
- ECHO – Echo pin listens for the reflected signal
- GND – Ground
Specifications:
- Power Supply: 5V DC
- Current Consumption: 15mA
- Operating Frequency: 40Hz
- Measurement Range: 2cm to 400cm
- Resolution: 0.3 cm
- Measurement Angle: 15 degrees
- Trigger Pulse Width: 10µs
DFPlayer Mini Overview
The DFPlayer Mini is a small MP3 player module capable of playing MP3, WAV, and WMA files. It is often used for projects requiring simple audio output. The module includes an SD card adapter that supports up to 32GB of FAT16/FAT32 cards, making it easy to store and play audio files.
Key Features:
- Supports formats like MP3 WAV and WMA
- Includes an SD card slot for up to 32GB (FAT16/FAT32).
- Simplified output directly connected to a speaker
- Powered by 3.2V or 5V DC
- Communicates with the microcontroller using the UART protocol.
Wiring
Ultrasonic Sensor to Arduino:
DFPlayer Mini to Arduino and Speaker::
Note:
Place a 1KOhm resistor between DFPlayer Mini’s RX pin and Arduino's Pin 3.
Circuit Diagram Code Breakdown:
Let's break down the code step by step.
#include <VARSTEP_ultrasonic.h> // Custom library for controlling the ultrasonic sensor.
#include "SoftwareSerial.h" // SoftwareSerial library for communication with the DFPlayer.
#include "DFRobotDFPlayerMini.h" // DFPlayer Mini control library.
VARSTEP_ultrasonic.h: This is a custom library to handle ultrasonic sensor operations, like measuring distance.
SoftwareSerial.h: This library allows the Arduino to create additional software-based serial communication ports, in this case, for the DFPlayer Mini.
DFRobotDFPlayerMini.h: This library is specifically designed to control the DFPlayer Mini module for playing audio files.
#define trigger_pin 8 // Pin connected to the TRIG pin of the ultrasonic sensor.
#define echo_pin 9 // Pin connected to the ECHO pin of the ultrasonic sensor
trigger_pin and echo_pin: These define the Arduino pins that are connected to the ultrasonic sensor’s TRIG and ECHO pins, respectively. The trigger pin sends the pulse, and the echo pin receives the reflected signal.
double distance_cm, distance_m; // Variables to store the distance in centimeters and meters.
distance_cm and distance_m: These are variables that store the measured distance in centimeters (distance_cm) and meters (distance_m), which will be calculated from the ultrasonic sensor.
VARSTEP_ultrasonic my_HCSR04(trigger_pin, echo_pin); // Create ultrasonic sensor object with defined pins.
my_HCSR04: This creates an instance of the ultrasonic sensor class (from the VARSTEP_ultrasonic library) using the specified trigger and echo pins. This object will be used to measure distances.
SoftwareSerial mySoftwareSerial(2, 3); // RX, TX: Serial communication for DFPlayer Mini.
DFRobotDFPlayerMini myDFPlayer; // Create DFPlayer Mini object.
mySoftwareSerial: This initializes a software-based serial communication on pins 2 (RX) and 3 (TX) to communicate with the DFPlayer Mini.
myDFPlayer: This creates an instance of the DFPlayer Mini class to control the playback of audio files.
unsigned long previousMillis = 0; // Variable for previous time for track playback.
unsigned long loopDelayMillis = 0; // Previous time for loop delay control.
const long interval = 2000; // 2 seconds interval for audio playback.
const long loopDelayInterval = 100; // 100ms loop delay interval.
bool trackPlayed = false; // Boolean flag to track if a sound has been played.
previousMillis, loopDelayMillis: These variables store timestamps to manage time intervals without using delay() function, making the code non-blocking.
interval: A constant that defines a 2-second gap between playing sounds. It prevents the same sound from being played continuously.
loopDelayInterval: A constant that defines a 100ms interval for smoother processing of loop tasks.
trackPlayed: A boolean flag used to ensure that a track plays only once per distance condition. If true, the track has already been played; otherwise, it's ready to play again.
setup() Function
void setup() {
mySoftwareSerial.begin(9600); // Start DFPlayer communication at 9600 baud.
Serial.begin(115200); // Begin serial communication at 115200 baud.
mySoftwareSerial.begin(9600): Starts serial communication between Arduino and DFPlayer Mini at a baud rate of 9600.
Serial.begin(115200): Starts serial communication with the computer at 115200 baud rate for debugging.
while (!Serial); // Wait for serial communication to start.
This waits until the serial connection is fully established, ensuring proper communication before moving forward.
if (!myDFPlayer.begin(mySoftwareSerial)) { // Initialize DFPlayer Mini.
Serial.println("Not initialized: Check connections and SD card.");
while (true); // Halt if initialization fails.
}
myDFPlayer.begin(): This initializes the DFPlayer Mini using the mySoftwareSerial object for communication. If the initialization fails (e.g., SD card missing or wrong connections), an error message is printed, and the program stops in an infinite loop (while(true)).
Serial.println("DFPlayer Mini initialized!");
myDFPlayer.setTimeOut(500); // Set serial communication timeout to 500ms.
myDFPlayer.volume(30); // Set volume to 30.
myDFPlayer.EQ(0); // Set equalizer to normal.
}
setTimeOut(500): This sets a 500-millisecond timeout for communication with the DFPlayer Mini.
volume(30): This sets the volume of the DFPlayer Mini to maximum (30 on a scale of 0-30).
EQ(0): This sets the equalizer mode to 'Normal'. Other options might include Pop, Rock, Bass, etc.
loop() Function:
void loop() {
unsigned long currentMillis = millis(); // Get the current time./code
<p class="paragraphes">millis(): This function returns the number of milliseconds since the Arduino started running. It helps in managing time-based tasks without blocking the code.</p>
/code:if (currentMillis - loopDelayMillis >= loopDelayInterval) {
loopDelayMillis = currentMillis; // Update loop delay.
This checks if 100 milliseconds have passed since the last loop execution. If true, it updates the loop delay timestamp (loopDelayMillis = currentMillis) and proceeds with the rest of the loop.
distance_cm = my_HCSR04.distance_cm(); // Measure distance in centimeters.
distance_m = my_HCSR04.distance_m(); // Measure distance in meters.
distance_cm(): Measures and returns the distance in centimeters using the ultrasonic sensor.
distance_m(): Measures and returns the distance in meters.
if (distance_cm == -1.0) {
Serial.println("No distance detected");
trackPlayed = false; // Reset track flag.
} else {/code
<p class="paragraphes">If distance_cm returns -1.0, it means no valid distance was detected, so it prints "No distance detected" and resets the trackPlayed flag. This ensures that a track can be played when a valid distance is detected again.</p>
/code: if (!trackPlayed || currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Update time.
This checks if a track has not been played (!trackPlayed) or if at least 2 seconds (interval = 2000) have passed since the last sound was played. If either condition is true, it updates the previousMillis to the current time to control when the next sound will play.
// Play specific audio based on the measured distance.
if (distance_cm <= 3.99 && distance_cm >= 3.80) {
myDFPlayer.play(1); // Play audio track 1.
} else if (distance_cm <= 5.99 && distance_cm >= 4.99) {
myDFPlayer.play(2); // Play audio track 2.
} else if (distance_cm <= 7.99 && distance_cm >= 6.99) {
myDFPlayer.play(3); // Play audio track 3.
} else if (distance_cm <= 9.9 && distance_cm >= 8.99) {
myDFPlayer.play(4); // Play audio track 4.
}
trackPlayed = true; // Mark track as played.
}
}/code
<p class="paragraphes">Based on the measured distance in centimeters, the code checks for specific distance ranges and plays a corresponding audio track:<br />
Track 1: Plays when the distance is between 3.80 cm and 3.99 cm.<br />
Track 2: Plays when the distance is between 4.99 cm and 5.99 cm.<br />
Track 3: Plays when the distance is between 6.99 cm and 7.99 cm.<br />
Track 4: Plays when the distance is between 8.99 cm and 9.9 cm.<br />
After playing a track, trackPlayed is set to true to prevent the same track from being played again immediately.</p>
/code: // Output distance to the Serial Monitor.
Serial.print("Distance: ");
Serial.print(distance_cm);
Serial.print(" cm | ");
Serial.print(distance_m);
Serial.println(" m");
}
}
This prints the measured distance in both centimeters and meters to the Serial Monitor for debugging purposes.
COMPLETE CODE#include <VARSTEP_ultrasonic.h> // Custom library for controlling the ultrasonic sensor.
#include "SoftwareSerial.h" // SoftwareSerial library for communication with the DFPlayer.
#include "DFRobotDFPlayerMini.h" // DFPlayer Mini control library.
#define trigger_pin 8 // Pin connected to the TRIG pin of the ultrasonic sensor.
#define echo_pin 9 // Pin connected to the ECHO pin of the ultrasonic sensor.
double distance_cm, distance_m; // Variables to store the distance in centimeters and meters.
VARSTEP_ultrasonic my_HCSR04(trigger_pin, echo_pin); // Create ultrasonic sensor object with defined pins.
SoftwareSerial mySoftwareSerial(2, 3); // RX, TX: Serial communication for DFPlayer Mini.
DFRobotDFPlayerMini myDFPlayer; // Create DFPlayer Mini object.
unsigned long previousMillis = 0; // Variable for previous time for track playback.
unsigned long loopDelayMillis = 0; // Previous time for loop delay control.
const long interval = 2000; // 2 seconds interval for audio playback.
const long loopDelayInterval = 100; // 100ms loop delay interval.
bool trackPlayed = false; // Boolean flag to track if a sound has been played.
void setup() {
mySoftwareSerial.begin(9600); // Start DFPlayer communication at 9600 baud.
Serial.begin(115200); // Begin serial communication at 115200 baud.
while (!Serial); // Wait for serial communication to start.
if (!myDFPlayer.begin(mySoftwareSerial)) { // Initialize DFPlayer Mini.
Serial.println("Not initialized: Check connections and SD card.");
while (true); // Halt if initialization fails.
}
Serial.println("DFPlayer Mini initialized!");
myDFPlayer.setTimeOut(500); // Set serial communication timeout to 500ms.
myDFPlayer.volume(30); // Set volume to 30.
myDFPlayer.EQ(0); // Set equalizer to normal.
}
void loop() {
unsigned long currentMillis = millis(); // Get the current time.
if (currentMillis - loopDelayMillis >= loopDelayInterval) {
loopDelayMillis = currentMillis; // Update loop delay.
distance_cm = my_HCSR04.distance_cm(); // Measure distance in centimeters.
distance_m = my_HCSR04.distance_m(); // Measure distance in meters.
if (distance_cm == -1.0) {
Serial.println("No distance detected");
trackPlayed = false; // Reset track flag.
} else {
if (!trackPlayed || currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Update time.
// Play specific audio based on the measured distance.
if (distance_cm <= 3.99 && distance_cm >= 3.80) {
myDFPlayer.play(1); // Play audio track 1.
} else if (distance_cm <= 5.99 && distance_cm >= 4.99) {
myDFPlayer.play(2); // Play audio track 2.
} else if (distance_cm <= 7.99 && distance_cm >= 6.99) {
myDFPlayer.play(3); // Play audio track 3.
} else if (distance_cm <= 9.9 && distance_cm >= 8.99) {
myDFPlayer.play(4); // Play audio track 4.
}
trackPlayed = true; // Mark track as played.
}
}
// Output distance to the Serial Monitor.
Serial.print("Distance: ");
Serial.print(distance_cm);
Serial.print(" cm | ");
Serial.print(distance_m);
Serial.println(" m");
}
}
How the Project Works
The HC-SR04 ultrasonic sensor measures the distance to an object.
The DFPlayer Mini plays different pre-recorded audio files from the SD card depending on the measured distance.The system checks the distance in real time and only plays an audio file if a specific range is detected. Once a track is played, it waits for 2 seconds before checking the distance again and playing another track if necessary.